"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMarkdownResolver = void 0;
const markdown_it_1 = __importDefault(require("markdown-it"));
const markdown_it_anchor_1 = __importDefault(require("markdown-it-anchor"));
const markdown_it_toc_done_right_1 = __importDefault(require("markdown-it-toc-done-right"));
const markdown_it_container_1 = __importDefault(require("markdown-it-container"));
const prismjs_1 = __importDefault(require("prismjs"));
/* ================================================================= */
// 解析需要高亮的语言配置
const resolveLanguage = (language, languageMap) => {
    const lang = language.toLowerCase();
    const langList = [
        language.toLowerCase(),
        languageMap[lang],
        languageMap["default"] || "js" // 使用默认语言
    ];
    // 查找已设置语言
    const grammarLang = langList.find((lang) => !!prismjs_1.default.languages[lang]);
    return {
        grammar: prismjs_1.default.languages[grammarLang],
        lang: grammarLang
    };
};
// languageMap: 当发现未加载语言时，映射为其他语言的映射表
const useResolveHighlight = (languageMap, codeHandler) => {
    return (codeSource, language) => {
        const { grammar, lang } = resolveLanguage(language, languageMap);
        const codeHTML = prismjs_1.default.highlight(codeSource, grammar, lang);
        // 外部传入 codeHandler 对高亮代码块进行二次处理
        return codeHandler({
            codeHTML: codeHTML,
            highlightLang: lang,
            codeSource: codeSource,
            sourceLang: language
        });
    };
};
/* ================================================================= */
// 默认 handler
const defaultHandler = (markdownIt, simpleMarkdownIt, loaderContext) => { };
// 默认 codeHandler
const defaultCodeHandler = (params) => params.codeHTML;
// 处理锚点链接的格式
const slugify = (s) => encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, "-"));
// 默认 container 渲染映射
const defaultContainerRender = {
    default(tokens, idx, simpleMarkdownIt, opts) {
        const { containerClass, titleClass, bodyClass } = opts;
        const { info, nesting } = tokens[idx];
        const [type, ...titles] = info.trim().split(" ");
        const containerClassList = type ? [containerClass, type] : [containerClass];
        const title = simpleMarkdownIt.render(titles.join(" "));
        // open 标签 nesting === 1
        if (nesting === 1) {
            return `
        <div class="${containerClassList.join(" ")}">
          <div class="${titleClass}">${title}</div>
          <div class="${bodyClass}">
      `;
        }
        // close 标签 nesting === -1
        else {
            return "</div></div>";
        }
    }
};
/* 用于生成一个 markdown 解析器函数 */
function useMarkdownResolver(options = {}, loaderContext) {
    const { preset = "default", contentClass = "imhjh-md-content", langPrefix = "imhjh-md-" } = options;
    const { linkify, typographer, quotes, html, xhtmlOut, breaks } = options;
    const { handler = defaultHandler, codeHandler = defaultCodeHandler, languageMap = {} } = options;
    const { useAnchor = false, anchorOptions } = options;
    const { useTOC = false, TOCOptions = {} } = options;
    const { useContainer = false, containerOptions = {} } = options;
    let TOCCode = "";
    const markdownIt = (0, markdown_it_1.default)(preset, {
        html: html,
        xhtmlOut: xhtmlOut,
        breaks: breaks,
        langPrefix: langPrefix,
        linkify: linkify,
        typographer: typographer,
        quotes: quotes,
        // 高亮函数，返回转义的HTML
        highlight: useResolveHighlight(languageMap, codeHandler)
    });
    // 用于解析 container 的 title 处的 markdown
    const simpleMarkdownIt = (0, markdown_it_1.default)(preset, {
        html: html,
        xhtmlOut: xhtmlOut,
        breaks: breaks,
        langPrefix: langPrefix,
        linkify: linkify,
        typographer: typographer,
        quotes: quotes,
        // 高亮函数，返回转义的HTML
        highlight: useResolveHighlight(languageMap, codeHandler)
    });
    // 添加锚点插件
    if (useAnchor) {
        const opts = Object.assign({ slugify, permalink: markdown_it_anchor_1.default.permalink.linkInsideHeader({
                class: "imhjh-md-anchor",
                placement: "before",
                space: false,
                symbol: "#"
            }) }, anchorOptions);
        markdownIt.use(markdown_it_anchor_1.default, opts);
    }
    // 添加目录插件
    if (useTOC) {
        const { callback } = TOCOptions, otherTOCOpts = __rest(TOCOptions, ["callback"]);
        const opts = Object.assign({ slugify, listType: "ul", containerClass: "imhjh-md-toc", linkClass: "imhjh-md-toc-anchor", callback: (tocCode, ast) => {
                TOCCode = tocCode;
                callback && callback(tocCode, ast);
            } }, otherTOCOpts);
        markdownIt.use(markdown_it_toc_done_right_1.default, opts);
    }
    // 添加自定义容器
    if (useContainer) {
        const opts = Object.assign(Object.assign({ containerClass: "imhjh-md-container", titleClass: "imhjh-md-container-title", bodyClass: "imhjh-md-container-body" }, containerOptions), { renderMap: Object.assign(Object.assign({}, defaultContainerRender), containerOptions.renderMap) });
        markdownIt.use(markdown_it_container_1.default, opts.containerClass, Object.assign({ 
            // 校验 容器名称 判断是否正确
            validate: (params) => {
                return true;
            }, 
            // 容器的 token 渲染方法
            render: (tokens, idx) => {
                const { info } = tokens[idx];
                const [type] = info.trim().split(" ");
                const { renderMap } = opts;
                const render = renderMap[type] || renderMap["default"];
                return render(tokens, idx, simpleMarkdownIt, opts);
            }, marker: ":" }, opts));
    }
    handler(markdownIt, simpleMarkdownIt, loaderContext);
    return {
        /* 生成的 markdown 实例 */
        markdownIt,
        /* 解析器 */
        resolver: (source) => {
            const code = markdownIt.render(source);
            const html = `<div class="${contentClass}">${code}</div>`;
            return { html: html, TOCCode: TOCCode };
        },
        /* 更新配置 */
        update: (updateOpts) => {
            const { handler = defaultHandler, codeHandler = defaultCodeHandler, languageMap = {} } = updateOpts, other = __rest(updateOpts, ["handler", "codeHandler", "languageMap"]);
            markdownIt.set(Object.assign({ highlight: useResolveHighlight(languageMap, codeHandler) }, other));
            simpleMarkdownIt.set(Object.assign({ highlight: useResolveHighlight(languageMap, codeHandler) }, other));
            handler(markdownIt, simpleMarkdownIt);
        }
    };
}
exports.useMarkdownResolver = useMarkdownResolver;
